/*************************************************
Author: byron
Date: 12/10/2012
Description:
Notes: 
*************************************************/

#ifndef __CStatusMgr_h__
#define __CStatusMgr_h__

#include "commerrno.h"
#include "CStatusCfg.h"
#include "../battle/CBattleMap.h"

class CStatusUnit;
class CPlayerAttr;
class CUserStatus;
class CSkillAffect;
class CSkillEffect;
class MsgReqGMPlayer;
class MsgAnsGMPlayer;
class CPlayerBaseInfo;
class CPlayerDetailInfo;
class CPlayerCacheData;
class CPlayerOnlineData;
class CPlayerSnsCommInfo;
class CPlayerDetailInfoEx1;
class MsgAnsMapInfo;
class CStatusObj;
class CStatusList;
class CBattleRole;

class CStatusMgr
{
public:
    enum STATUS_TRIGGER_WAY_TAG
    {
        STATUS_TRIGGER_ENTER_BATTLE         = 1,    //进入战斗时触发 +
        STATUS_TRIGGER_HIT_ENEMY            = 2,    //命中敌人时触发 攻击者触发+
        STATUS_TRIGGER_ENEMY_HIT            = 25,   //命中敌人时触发 被攻击者触发+
        STATUS_TRIGGER_GET_HURT             = 3,    //受伤掉血时触发 +
        STATUS_TRIGGER_SELF_ATTR_CHG        = 4,    //自身属性改变时触发 +
        STATUS_TRIGGER_SELF_ATTR_LIMIT      = 5,    //自身属性临界时触发 +
        STATUS_TRIGGER_OBJ_ATTR_LIMIT       = 6,    //目标属性临界时触发 +
        STATUS_TRIGGER_ATK_DOUBLE           = 7,    //攻击暴击时触发 +
        STATUS_TRIGGER_BY_DOUBLE            = 8,    //受击被暴击时触发 +
        STATUS_TRIGGER_ATK_DODGE            = 9,    //攻击被闪避时触发 +
        STATUS_TRIGGER_ATK_BLOCK            = 10,   //攻击被格挡时触发 +
        STATUS_TRIGGER_DODGE_ATK            = 11,   //闪避攻击时触发 +
        STATUS_TRIGGER_BLOCK_ATK            = 12,   //格挡攻击时触发 计算伤害之后+
        STATUS_TRIGGER_BLOCK_ATK_BEFORE     = 28,   //格挡攻击时触发 计算伤害之前+
        STATUS_TRIGGER_SELF_DIE             = 14,   //自己死亡时触发 +
        STATUS_TRIGGER_SELF_DIE_OR_LIFE     = 27,   //自己死亡时触发 有可能豁免+
        STATUS_TRIGGER_SELF_DIE_ALL_DIE     = 29,   //自己死亡时触发 且是本方最后一个死亡+
        STATUS_TRIGGER_TEAMMATE_DIE         = 15,   //队友死亡时触发 +
        STATUS_TRIGGER_ATK_OBJ_DIE          = 16,   //攻击目标死亡时触发 +
        STATUS_TRIGGER_CAST_MAGIC_SKILL     = 18,   //发动幻化技能时触发 +
        STATUS_TRIGGER_NORMAL_SKILL_HIT     = 19,   //普通攻击命中敌人时触发 +
        STATUS_TRIGGER_NORMAL_SKILL_DOUBLE  = 20,   //普通攻击暴击敌人时触发 +
        STATUS_TRIGGER_TURN_START           = 21,   //回合行动时触发 移动前 发出技能前 +
        STATUS_TRIGGER_TURN_ACTION          = 13,   //回合行动时触发 攻击者移动后 发出技能效果前 +
        STATUS_TRIGGER_TURN_ACT_OBJ_LIMIT   = 23,   //回合行动时触发 攻击者移动后 发出技能效果前 要求检查目标临界值 +
        STATUS_TRIGGER_TURN_OVER            = 22,   //回合行动结束时触发 +
        STATUS_TRIGGER_TURN_OVER_AND_HIT    = 26,   //回合行动结束时触发 有命中目标+
        STATUS_TRIGGER_CALC_SKILL_EFF       = 17,   //计算伤害时触发 +
        STATUS_TRIGGER_CALC_ATK_OBJ_LIMIT   = 24,   //计算伤害时触发 要求检查目标临界值 +
    };

    enum STATUS_APPEAR_TYPE_TAG
    {
        STATUS_APPEAR_TYPE_NORMAL       = 0,            //正常SkillAffect之后输出
        STATUS_APPEAR_TYPE_AHEAD        = (0x1 << 1),   //提前SkillAffect之前输出
    };

    CStatusMgr()
    {
    }

    virtual ~CStatusMgr()
    {
    }

    static int CountSize()
    {
        return CStatusCfg::CountSize();
    }

    int Init(const char * sBuff)
    {
        if (!sBuff)
        {
            return RET_SYS_NULL_POINTER;
        }

        return _stStatusCfg.Init(sBuff);
    }

    int LoadConfig(const char* szCfgPath);

    int FindStatusCfg(int iResID)
    {
        return _stStatusCfg.FindConfig(iResID);
    }

    CStatusCfgData& GetStatusCfg(int iIndex)
    {
        return _stStatusCfg.GetConfig(iIndex);
    }

    int FindStatusGroup(int iResID)
    {
        return _stStatusCfg.FindGroupConfig(iResID);
    }

    CStatusGroup& GetStatusGroup(int iIndex)
    {
        return _stStatusCfg.GetGroupConfig(iIndex);
    }

    int FindStatus(CPlayerCacheData& stPlayerCache, int iResID);

    CStatusUnit& GetStatus(CPlayerCacheData& stPlayerCache, int iIndex);

    int FindStatus(CStatusList& stStatusList, int iResID);

    bool IsNeedSendStatusList(int iStatusID);

    int DelStatus(CPlayerCacheData& stPlayerCache, int iStatusID,
            bool bSendStatusList);

    int AddStatus(CPlayerCacheData& stPlayerCache, int iStatusID, int iEndTime,
            short shActID, bool bSendStatusList);

    int AddStatus(CStatusList& stStatusList, int iStatusID, int iAddNum,
            int iActType);

    int FindCfgSkillEffect(int iStatusID);

    CSkillEffect& GetCfgSkillEffect(int iIndex);

    int FindSkillAffect(int iStatusID);

    CSkillAffect& GetSkillAffect(int iIndex);

    unsigned int GetBufferID(int iStatusID);

    int FindSkillEffect(int iStatusID);

    CSkillEffect& GetSkillEffect(int iIndex);

    int GetStatusAttr(CUserStatus& stUserStatus,
            CPlayerAttr& stPlayerAttr);

    int CalcStatusAddAttr(MAP_GRID_MULTI& stMapGridMulti,
        CSkillAffect& stSkillAffect, CStatusObj& stStatusObj);

    int CalcStatusAddAttr(CSkillAffect& stSkillAffect, CPlayerAttr& stNewAttr,
            CPlayerAttr& stBaseAttr, CStatusObj& stStatusObj);

    int GetStatusList(int iStatusGroupID, CStatusList& stStatusList);

    int GetStatusList(unsigned int uiGID, CStatusList& stStatusList,
            int iActType);

    int GMDealStatus(CPlayerCacheData& stPlayerCache,
            MsgReqGMPlayer& stReq, MsgAnsGMPlayer& stAns);

    void GetUserStatus(CPlayerBaseInfo& stPlayerBase,
            CPlayerDetailInfo& stPlayerDetail,
            CPlayerOnlineData& stPlayerOnline,
            CPlayerCacheData& stPlayerCache, MsgAnsMapInfo& stMsgAnsMap);

    void GetUserStatusAndTitle(CPlayerBaseInfo& stPlayerBase,
            CPlayerDetailInfo& stPlayerDetail,
            CPlayerOnlineData& stPlayerOnline, CPlayerCacheData& stPlayerCache,
            CPlayerSnsCommInfo& stPlayerSnsComm, MsgAnsMapInfo& stMsgAnsMap,
            bool bResetPosInfo);

    void NotifyUserStatusToMapByGID(unsigned int uiGID);

    void NotifyUserStatusToMap(CPlayerBaseInfo& stPlayerBase,
            CPlayerDetailInfo& stPlayerDetail,
            CPlayerOnlineData& stPlayerOnline, CPlayerCacheData& stPlayerCache,
            CPlayerSnsCommInfo& stPlayerSnsComm);

    void NotifyUserStatusToSelfByGID(unsigned int uiGID);

    void NotifyUserStatusToSelf(CPlayerBaseInfo& stPlayerBase,
            CPlayerDetailInfo& stPlayerDetail,
            CPlayerOnlineData& stPlayerOnline, CPlayerCacheData& stPlayerCache,
            CPlayerSnsCommInfo& stPlayerSnsComm);

    void NotifyUserStatusToClanMember(unsigned int uiClanID);

    void UpdateUserStatus(CPlayerBaseInfo& stPlayerBase,
            CPlayerDetailInfo& stPlayerDetail,
            CPlayerOnlineData& stPlayerOnline, CPlayerCacheData& stPlayerCache,
            CPlayerSnsCommInfo& stPlayerSnsComm,
            CPlayerDetailInfoEx1& stPlayerDetailEx1, int iTimeGap);

    int StatusBattleVideo(CStatusCfgData& stCfgData, CBattleRole& stBattleRole,
            CBattleRole& stBattleTarget, CStatusObj& stStatusObj,
            bool& bHaveTriggerVideo);

    int StatusMountVideo(CStatusCfgData& stCfgData, CBattleRole& stBattleRole,
            CBattleRole& stBattleTarget, CStatusObj& stStatusObj,
            bool& bHaveTriggerMount);

    int StatusSkillAffectRoleAttr(CBattleRole& stBattleRole,
            CBattleRole& stBattleTarget, CStatusCfgData& stCfgData,
            CStatusObj& stStatusObj, bool& bNeedTrigger);

    int StatusSkillAffect(CBattleRole& stBattleRole, int iTriggerWay,
            int iAttrType, int iAuxAddNum);

    int StatusSkillAffect(CBattleRole& stBattleRole, int iTriggerWay,
            int iAuxAddNum);

    //调试用 输出大量日志
    void DumpStatusTarget(MAP_GRID_MULTI& stMapGridMulti);

    void DumpStatusObj(CStatusObj& stStatusObj);

    void DumpStatusList(CStatusList& stStatusList);

    //状态ID存在性的简单检查
    int IsValidStatusID(int iStatusID);
    //状态组存在性的简单检查
    int IsValidStatusGroup(int iGroupID);

private:
    int         _iRandomVal;
    CStatusCfg _stStatusCfg;
};

#endif //__CStatusMgr_h__

